package com.kyrie.lib_sys.utils.learn.leetCode;

import org.checkerframework.checker.units.qual.A;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 力扣----->双指针篇
 *
 * @author heefM
 * @date 2025-07-27
 */
public class leetCode_Index {

    public static void main(String[] args) {

        //移动零  (双指针)
        System.out.println(Arrays.toString(moveZeroes(new int[]{0, 1, 0, 3, 12})));
        System.out.println("----------------------------------------------------------------------");

        //盛最多水的容器
        System.out.println(maxArea(new int[]{1, 8, 6, 2, 5, 4, 8, 3, 7}));

        System.out.println("----------------------------------------------------------------------");

        //三数之和
        System.out.println(threeSum(new int[]{-1, 0, 1, 2, -1, -4}));

        System.out.println("----------------------------------------------------------------------");
    }


    /**
     * 移动零  (双指针)
     *
     * @param nums
     */
    public static int[] moveZeroes(int[] nums) {
        int index = 0; //指针
        int count = nums.length;

        //遍历数组(将非零数放前面)  将是0的数被后面的数替换
        for (int i = 0; i < count; i++) {
            if (nums[i] == 0) { //如果当前数是0;我们就跳过操作0这个数
                continue;
            }
            nums[index] = nums[i];//将当前数,替换掉index位置的数
            index++;//由于当前指针的数据被替换了, 所以index指针要+1
        }
        //置零 (将最后的数置零(有几个0就置几个))
        for (int i = index; i < count; i++) {
            nums[i] = 0;
        }
        return nums;
    }

    /**
     * 盛最多水的容器 (双指针)
     *
     * @param nums
     * @return
     */
    public static int maxArea(int[] nums) {
        int left = 0;
        int right = nums.length - 1;
        int result = 0;
        int area = 0;
        //只要左边和右边不重叠
        while (left < right) {
            area = Math.min(nums[left], nums[right]) * (right - left);
            result = Math.max(area, result);
            //如果左边长度(下标)小，则左边向右移动
            if (nums[left] < nums[right]) {
                left++;
            } else {
                right--;
            }
        }

        return result;
    }


    /**
     * 三数之和 (双指针)
     *
     * @param nums
     * @return
     */
    public static ArrayList<List<Integer>> threeSum(int[] nums) {
        ArrayList<List<Integer>> list = new ArrayList<>();
        Arrays.sort(nums);

        //拿第一个数
        for (int i = 0; i < nums.length; i++) {  //-1,-1,0,1,2

            //如果当前值与前一个值相等,则跳过
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            int r = nums.length - 1;//定义最右边索引
            int target = -nums[i]; //目标值
            //定义一个比i大一位的左指针向右移动,避免重复   l: 表示左边第一个索引
            for (int l = i + 1; l < r; l++) {

                //如果左边值与右边值相等,且左边与右边不重叠
                if (l > i + 1 && nums[l] == nums[l - 1]) {
                    continue;
                }
                //如果左边与右边相加大于目标值,且左边与右边不重叠
                while (nums[l] + nums[r] > target && l < r) {
                    r--; //大于目标值,向左移动
                }
                if (r == l) {
                    break;
                }
                if (nums[l] + nums[r] == target) {
                    list.add(Arrays.asList(nums[i], nums[l], nums[r]));
                }

            }

        }
        return list;
    }


}
